//
//  Localizator.swift
//  JT-Architecture
//
//  Created by 果咱 on 2020/12/14.
//

import Foundation

public func LocalizedString(_ key: String) -> String {
    return Localizator.localizedStringForKey(key)
}

@discardableResult
public func SetLanguage(_ type: LanguageType) -> Bool {
    return Localizator.setLanguage(type)
}

public func onLanguageChanged(dependence: AnyObject, triggerImmediately: Bool = true, block: @escaping ()->()) {
    if triggerImmediately { block() }
    let languageBlock = DependenceBlock(block: block, dependence: dependence)
    Localizator.languageBlocks.append(languageBlock)
}

private struct DependenceBlock {
    var block: () -> ()
    weak var dependence: AnyObject?
}

public class Localizator {
    
    private static var dicoLocalization: NSDictionary?
    
    fileprivate static var languageBlocks = [DependenceBlock]()
 
    private static let kSaveLanguageDefaultKey = "kSaveLanguageDefaultKey"
    
    // MARK: - Public properties
    public static var updatedLanguageType: LanguageType?
    
    fileprivate static func loadDictionaryForLanguage(_ type: LanguageType) -> Bool {
        let ext = type.fileName
        if let path = Bundle(for: object_getClass(self)!).url(forResource: "Localizable", withExtension: "strings", subdirectory: nil, localization: ext)?.path {
            if FileManager.default.fileExists(atPath: path) {
                updatedLanguageType = type
                dicoLocalization = NSDictionary(contentsOfFile: path)
                return true
            }
        }
        return false
    }
    
    fileprivate static func localizedStringForKey(_ key: String) -> String {
        if let dico = dicoLocalization {
            if let localizedString = dico[key] as? String {
                return localizedString
            } else {
                return key
            }
        } else {
            return NSLocalizedString(key, comment: key)
        }
    }
    
    @discardableResult
    public static func setLanguage(_ newType: LanguageType, force: Bool = false) -> Bool {
        if newType == updatedLanguageType && !force {
            return false
        }
        
        UserDefaults.standard.set([newType.fileName], forKey: "AppleLanguages")
        UserDefaults.standard.synchronize()
        
        if loadDictionaryForLanguage(newType) {
            DispatchQueue.main.async {
                NotificationCenter.default.post(name: .languageChanged, object: nil)
            }
            Localizator.languageBlocks.removeAll { return $0.dependence == nil }
            Localizator.languageBlocks.forEach{ $0.block() }
            return true
        }
        return false
    }
    
    public static func localTimeZoneName() -> String {
        return TimeZone.current.identifier
    }
    
    public static func localTimeZoneAbbreviation() -> String {
        let timeZone = TimeZone.current.abbreviation() ?? "UTC+8"
        return String(timeZone.dropFirst(3))
    }
}
